//
//  Mantle+Utils.m
//  YZStock
//
//  Created by fenchol on 15/8/28.
//  Copyright (c) 2015年 cqjr. All rights reserved.
//

#import "Mantle+Utils.h"
#import "MTLJSONAdapter.h"
#import "MTLModel.h"
#import "MTLValueTransformer.h"

NSString *const MTLLongStringTransformerName = @"MTLLongStringTransformerName";
NSString *const MTLStringLongTransformerName = @"MTLStringLongTransformerName";
NSString *const MTLStringDoubleTransformerName = @"MTLStringDoubleTransformerName";
NSString *const MTLDoubleDateTransformerName = @"MTLDoubleDateTransformerName";

@implementation NSValueTransformer (mantle_utils)

+ (void)load
{
    @autoreleasepool {
        MTLValueTransformer *numberStringTransformer = [self longStringTransformer];
        [NSValueTransformer setValueTransformer:numberStringTransformer forName: MTLLongStringTransformerName];
        MTLValueTransformer *stringLongTransformer = [self stringLongTransformer];
        [NSValueTransformer setValueTransformer: stringLongTransformer forName: MTLStringLongTransformerName];
        
        MTLValueTransformer *stringDoubleTransformer = [self stringDoubleTransformer];
        [NSValueTransformer setValueTransformer: stringDoubleTransformer forName: MTLStringDoubleTransformerName];
        
        MTLValueTransformer *doubleDateTransformer = [self doubleDateTransformer];
        [NSValueTransformer setValueTransformer:doubleDateTransformer forName:MTLDoubleDateTransformerName];
    }
}

+ (MTLValueTransformer *)longStringTransformer
{
    return [MTLValueTransformer transformerUsingForwardBlock:^id(NSNumber *value, BOOL *success, NSError *__autoreleasing *error) {
        if (value == nil) {
            return nil;
        }
        else if ([value isKindOfClass: [NSNumber class]])
        {
            *success = YES;
            return [value stringValue];
        }
        
        else if ([value isKindOfClass: [NSString class]])
        {
            *success = YES;
            return value;
        }
        if (error != NULL) {
            NSDictionary *userInfo = @{
                                       NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert number to string", @""),
                                       NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected an NSNumber, got: %@.", @""), value],
                                       MTLTransformerErrorHandlingInputValueErrorKey : value
                                       };
            
            *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo];
        }
        return nil;
    } reverseBlock:^id(NSString *value, BOOL *success, NSError *__autoreleasing *error) {
        if ([value isKindOfClass: [NSString class]])
        {
            *success = YES;
            return [NSNumber numberWithLong: [value integerValue]];
        }
        if (error != NULL) {
            NSDictionary *userInfo = @{
                                       NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert string to number", @""),
                                       NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected an NSNumber, got: %@.", @""), value],
                                       MTLTransformerErrorHandlingInputValueErrorKey : value
                                       };
            
            *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo];
        }
        return nil;
    }];
}

+ (MTLValueTransformer *)stringLongTransformer
{
    return [MTLValueTransformer transformerUsingForwardBlock:^id(NSString *string, BOOL *success, NSError *__autoreleasing *error) {
        if ([string isKindOfClass: [NSNumber class]])
        {
            *success = YES;
            return string;
        }
        
        else if ([string isKindOfClass: [NSString class]])
        {
            *success = YES;
            long long value = [string longLongValue];
            return @(value);
        }
        else if (string == nil)
        {
            return nil;
        }
        if (error != NULL) {
            NSDictionary *userInfo = @{
                                       NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert string to long long", @""),
                                       NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected an NSString, got: %@.", @""), string],
                                       MTLTransformerErrorHandlingInputValueErrorKey : string
                                       };
            
            *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo];
        }
        return nil;
    } reverseBlock:^id(NSNumber *value, BOOL *success, NSError *__autoreleasing *error) {
        assert(value);
        return nil;
    }];

}


+ (MTLValueTransformer *)stringDoubleTransformer
{
    return [MTLValueTransformer transformerUsingForwardBlock:^id(NSString *string, BOOL *success, NSError *__autoreleasing *error) {
        if ([string isKindOfClass: [NSNumber class]])
        {
            *success = YES;
            return string;
        }
        
        else if ([string isKindOfClass: [NSString class]])
        {
            *success = YES;
            double value = [string doubleValue];
            return @(value);
        }
        else if (string == nil)
        {
            return nil;
        }
        if (error != NULL) {
            NSDictionary *userInfo = @{
                                       NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert string to long long", @""),
                                       NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected an NSString, got: %@.", @""), string],
                                       MTLTransformerErrorHandlingInputValueErrorKey : string
                                       };
            
            *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo];
        }
        return nil;
    } reverseBlock:^id(NSNumber *value, BOOL *success, NSError *__autoreleasing *error) {
        assert(value);
        return nil;
    }];
    
}

+ (MTLValueTransformer *)doubleDateTransformer{
    return [MTLValueTransformer transformerUsingForwardBlock:^id(id value, BOOL *success, NSError *__autoreleasing *error) {
        if ([value isKindOfClass: [NSString class]] || [value isKindOfClass: [NSNumber class]])
        {
            *success = YES;
            return [NSDate dateWithTimeIntervalSince1970:[value doubleValue]/1000];
        }
        else if (value == nil)
        {
            return nil;
        }
        if (error != NULL) {
            NSDictionary *userInfo = @{
                                       NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert string to long long", @""),
                                       NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected an NSString, got: %@.", @""), value],
                                       MTLTransformerErrorHandlingInputValueErrorKey : value
                                       };
            
            *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo];
        }
        return nil;
    } reverseBlock:^id(NSNumber *value, BOOL *success, NSError *__autoreleasing *error) {
        assert(value);
        return nil;
    }];
}

@end
